package cn.schoolwow.quickdao.module.entity.flow.annotation;

import cn.schoolwow.quickdao.domain.QuickDAOConfig;
import cn.schoolwow.quickdao.domain.entity.Entity;
import cn.schoolwow.quickdao.domain.entity.Property;
import cn.schoolwow.quickdao.module.entity.flow.common.GetEntityAllFieldsFlow;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

public class ScanPropertyAnnotationFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        QuickDAOConfig quickDAOConfig = flowContext.checkInstanceData(QuickDAOConfig.class);

        flowContext.executeFlowList(new GetEntityAllFieldsFlow());
        List<Field> fieldList = (List<Field>) flowContext.checkData("fieldList");
        Entity entity = (Entity) flowContext.checkData("entity");

        for (Field field : fieldList) {
            if(null!=quickDAOConfig.entityOption.entityListener){
                boolean ignoreProperty = quickDAOConfig.entityOption.entityListener.ignoreProperty(entity, field);
                if(ignoreProperty){
                    continue;
                }
            }
            //跳过实体包类
            boolean compositeProperty = (boolean) flowContext.startFlow(new CheckCompositePropertyFlow())
                    .printTrace(false)
                    .putTemporaryData("clazz", field.getType())
                    .execute()
                    .checkData("compositeProperty");
            if (compositeProperty) {
                if (!entity.compositeFieldMap.containsKey(field.getType().getName())) {
                    entity.compositeFieldMap.put(field.getType().getName(), new ArrayList<>());
                }
                entity.compositeFieldMap.get(field.getType().getName()).add(field.getName());
                continue;
            }
            Property property = (Property) flowContext.startFlow(new GetPropertyAnnotationFlow())
                    .printTrace(false)
                    .putTemporaryData("field", field)
                    .execute()
                    .checkData("property");
            property.field = field;
            entity.properties.add(property);
        }
    }

    @Override
    public String name() {
        return "扫描实体类字段注解";
    }

}
